<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="coinfaces">

        <title>Linux 0.11里volatile的用法</title>

    <link rel="stylesheet" href="../../theme/css/style.css">
    <link rel="stylesheet" href="../../theme/css/pygments.css">



</head>

<body>
    <div class="content">
<h1>Linux 0.11里volatile的用法</h1>    <p>
        under
            <a href="../../tags/kernel/">kernel</a>
            <a href="../../tags/c/">c</a>
    </p>
    <p>
        in <a href="../../categories/tech/">tech</a>
    </p>
    <p>Published: 2016-07-09</p>


    <p>如果在<a class="reference external" href="http://oldlinux.org/Linux.old/Linux-0.11/sources/system/linux-0.11.tar.Z">Linux 0.11源代码</a>里搜索volatile的使用：</p>
<pre class="literal-block">
$ grep volatile -R
lib/_exit.c:volatile void _exit(int exit_code)
include/asm/io.h:__asm__ volatile (&quot;inb %%dx,%%al&quot;:&quot;=a&quot; (_v):&quot;d&quot; (port)); \
include/asm/io.h:__asm__ volatile (&quot;inb %%dx,%%al\n&quot; \
include/unistd.h:__asm__ volatile (&quot;int $0x80&quot; \
include/unistd.h:__asm__ volatile (&quot;int $0x80&quot; \
include/unistd.h:__asm__ volatile (&quot;int $0x80&quot; \
include/unistd.h:__asm__ volatile (&quot;int $0x80&quot; \
include/unistd.h:volatile void exit(int status);
include/unistd.h:volatile void _exit(int status);
include/linux/sched.h:extern long volatile jiffies;
include/linux/kernel.h:volatile void panic(const char * str);
mm/memory.c:volatile void do_exit(long code);
mm/memory.c:static inline volatile void oom(void)
kernel/sched.c:long volatile jiffies=0;
kernel/panic.c:volatile void panic(const char * s)
kernel/signal.c:volatile void do_exit(int error_code);
fs/bitmap.c:__asm__ __volatile__(&quot;btsl %2,%3\n\tsetb %%al&quot;: \
fs/bitmap.c:__asm__ __volatile__(&quot;btrl %2,%3\n\tsetnb %%al&quot;: \
</pre>
<p>这里有三种用法：变量声明、内联汇编和函数声明。</p>
<div class="section" id="id2">
<h2>变量声明</h2>
<p><tt class="docutils literal">jiffies</tt>随时可能被时钟中断修改，因此必须声明为<tt class="docutils literal">volatile</tt>（易变的），否则编译器看到一段程序里没有修改它的值，就可能将其优化而缓存到寄存器里，造成程序无法知道系统时间的变化。总之<tt class="docutils literal">volatile</tt>用来声明随时会被外部因素修改的变量，在多线程或内存映射IO的应用程序里有很多这样的变量。</p>
</div>
<div class="section" id="id3">
<h2>内联汇编</h2>
<p>内联汇编里的<tt class="docutils literal">volatile</tt>或<tt class="docutils literal">__volatile__</tt>用于限制编译器对这段代码进行执行顺序上的优化（如移到循环外面，改变执行次序或干脆不执行），但这并不能阻止CPU优化指令的执行顺序，详见<a class="reference external" href="http://stackoverflow.com/questions/26456510/what-does-asm-volatile-do-in-c">Stackoverflow上的这篇回答</a>和<a class="reference external" href="http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html">这篇介绍GCC内联汇编的文章</a>。</p>
</div>
<div class="section" id="id6">
<h2>函数声明</h2>
<p>写在函数声明里的<tt class="docutils literal">volatile</tt>也和编译优化有点关系，但它的主要作用是告诉GCC优化时不需要考虑函数返回的情况，因为函数不会返回（要么退出程序，要么执行长跳转），现在的GCC已经不支持这种写法了，而是采用<tt class="docutils literal">noreturn</tt>属性，我觉得这样更好，因为前者有滥用volatile的嫌疑。在<a class="reference external" href="https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html">GCC 4.0.0文档里</a>，可以看到类似叙述：</p>
<blockquote>
<p>The attribute noreturn is not implemented in GCC versions earlier than 2.5. An alternative way to declare that a function does not return, which works in the current version and in some older versions, is as follows:</p>
<pre class="literal-block">
typedef void voidfn ();
volatile voidfn fatal;
</pre>
</blockquote>
<p>（完）</p>
</div>

    </div>
<nav class="nav sidebar">
    <div class="siteinfo">
        <div class="sitename"><a href="../..">coinfaces</a></div>
        <div class="tagline">Another Side of Life</div>
    </div>

        <a href="../../categories/">categories</a>
        <a href="../..">&larr; Home</a>
</nav><footer class="footer">
    <span>
        &copy; jpli &middot;
        under <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>
    </span>
    |
    <span>
        Powered by:
        <a href="http://blog.getpelican.com/">Pelican</a>
    </span>
</footer></body>
</html>